package org.example.controller;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.example.common.Result;
import org.example.config.JwtConfig;
import org.example.exception.ServiceException;
import org.example.model.request.UserRequest;
import org.example.model.request.WechatLoginRequest;
import org.example.model.response.WechatLoginResponse;
import org.example.model.WechatUserInfo;
import org.example.service.WechatService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;

@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "*") // 允许跨域请求
@Tag(name = "微信登录接口")
public class WechatLoginController {

    private final WechatService wechatService;
//    private final String jwtSecret = "your_jwt_secret"; // 生成JWT的密钥，一般使用环境变量或配置文件管理
    private final JwtConfig jwtConfig; // 使用 JwtConfig


    public WechatLoginController(WechatService wechatService, JwtConfig jwtConfig) {
        this.wechatService = wechatService;
        this.jwtConfig = jwtConfig;
    }


    /**
     * 微信一键登录
     * @param request
     * @return
     */
    @Operation(summary = "微信一键登录")
    @PostMapping("/login/wechat")
    public Result<WechatLoginResponse> login(@RequestBody WechatLoginRequest request)  {
        // 根据code获取该用户信息
        WechatUserInfo wechatUserInfo = wechatService.wxLogin(request.getCode());
        // 生成标准令牌
        String token = Jwts.builder()
                .setSubject(wechatUserInfo.getOpenid())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + jwtConfig.getTokenExpiration()))
                .signWith(SignatureAlgorithm.HS512, jwtConfig.getJwtSecret())
                .compact();

        // 生成临时令牌
        String temporaryToken = Jwts.builder()
                .setSubject(wechatUserInfo.getOpenid())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + jwtConfig.getTemporaryTokenExpiration()))
                .signWith(SignatureAlgorithm.HS512, jwtConfig.getJwtSecret())
                .compact();
                
        // 生成刷新令牌
        String refreshToken = Jwts.builder()
                .setSubject(wechatUserInfo.getOpenid())
                .setIssuedAt(new Date())
                .claim("type", "refresh")
                .setExpiration(new Date(System.currentTimeMillis() + jwtConfig.getRefreshTokenExpiration()))
                .signWith(SignatureAlgorithm.HS512, jwtConfig.getJwtSecret())
                .compact();

        // 构建响应
        WechatLoginResponse response = WechatLoginResponse.builder()
                .uid(String.valueOf(wechatUserInfo.getId() + 100100))
                .token(token)
                .temporaryToken(temporaryToken)
                .refreshToken(refreshToken)
                .build();

        return Result.success(response);
    }

    @PostMapping("/UserInfo")
    public void userInfo(@RequestBody UserRequest userRequest) {
        wechatService.setUserInfo(userRequest);
    }
    
    /**
     * 刷新令牌
     * 使用刷新令牌获取新的访问令牌
     * @param refreshToken 刷新令牌
     * @return 新的令牌信息
     */
    @Operation(summary = "刷新访问令牌")
    @PostMapping("/token/refresh")
    public ResponseEntity<?> refreshToken(@RequestBody HashMap<String, String> request) {
        String refreshToken = request.get("refreshToken");
        
        if (refreshToken == null) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                .body(Result.error("刷新令牌不能为空"));
        }
        
        try {
            // 验证刷新令牌
            Claims claims = Jwts.parser()
                    .setSigningKey(jwtConfig.getJwtSecret())
                    .parseClaimsJws(refreshToken)
                    .getBody();
            
            // 检查是否是刷新令牌
            String tokenType = (String) claims.get("type");
            if (!"refresh".equals(tokenType)) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(Result.error("无效的刷新令牌"));
            }
            
            // 获取用户openid
            String openid = claims.getSubject();
            
            // 生成新的标准令牌
            String newToken = Jwts.builder()
                    .setSubject(openid)
                    .setIssuedAt(new Date())
                    .setExpiration(new Date(System.currentTimeMillis() + jwtConfig.getTokenExpiration()))
                    .signWith(SignatureAlgorithm.HS512, jwtConfig.getJwtSecret())
                    .compact();
            
            // 构建响应
            HashMap<String, String> response = new HashMap<>();
            response.put("token", newToken);
            
            return ResponseEntity.ok(Result.success(response));
            
        } catch (ExpiredJwtException e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                .body(Result.error("刷新令牌已过期，请重新登录"));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                .body(Result.error("刷新令牌验证失败"));
        }
    }

}
